package com.itheima.controller;

import com.alibaba.dubbo.config.annotation.Reference;
import com.itheima.constant.MessageConst;
import com.itheima.entity.Result;
import com.itheima.service.MemberService;
import com.itheima.service.ReportService;
import com.itheima.service.SetmealService;
import com.itheima.utils.TransferIdUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

import static com.itheima.utils.TransferIdUtils.getAgeByBirth;

/**
 * @author 黑马程序员
 * @Company http://www.ithiema.com
 * @Version 1.0
 */
@RestController
@RequestMapping("/report")
@Slf4j
public class ReportController {

    @Reference
    MemberService memberService;

    /**
     * {
     * flag: true ,
     * message: '会员数量统计成功！',
     * data: {
     * months: ['2020-01','2020-02'],
     * memberCount:[10, 20]
     * }
     * }
     *
     * @return
     */
    @RequestMapping("/getMemberReport")
    public Result getMemberReport() {
        Map<String, Object> map = memberService.getMemberReport();
        return new Result(true, MessageConst.GET_MEMBER_NUMBER_REPORT_SUCCESS, map);
    }

    @RequestMapping("/getMemberReportByDate")
    public Result getMemberReportByDate(@RequestBody List<String> periodOfDate){
        log.debug("periodOfDate=============="+periodOfDate);
        //格式化获取到的前端数据---2020-03
        String startDate=monthAddOne(periodOfDate.get(0));
        String endDate=monthAddOne(periodOfDate.get(1));

        log.debug("startDate======="+startDate);
        log.debug("endDate============="+endDate);
        Map<String,Object> map=memberService.getMemberReportByDate(startDate,endDate);
        log.debug("map=========="+map);
        return new Result(true,MessageConst.GET_MEMBER_NUMBER_REPORT_SUCCESS,map);
    }

    private String monthAddOne(String date){
        DateFormat df=new SimpleDateFormat("yyyy-MM");
        try {
            Calendar ct=Calendar.getInstance();
            ct.setTime(df.parse(date));
            ct.add(Calendar.MONTH, +1);
            return df.format(ct.getTime());
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }
    @Reference
    private SetmealService setmealService;

    /**
     * 套餐占比统计
     *
     * @return
     */
    @RequestMapping("/getSetmealReport")
    public Result getSetmealReport() {
        log.debug("ReportController: getSetmealReport ");
        // 获取套餐占比数据
        List<Map<String, Object>> setmealCountList = setmealService.findSetmealCount();
        // 获取套餐名称
        List<String> setmealNames = new ArrayList<>();
        for (Map<String, Object> mapSetmeal : setmealCountList) {
            String setmealName = (String) mapSetmeal.get("name");
            setmealNames.add(setmealName);
        }
        // 构建返回数据
        Map<String, Object> mapData = new HashMap<>();
        mapData.put("setmealCount", setmealCountList);
        mapData.put("setmealNames", setmealNames);
        log.debug("套餐预约占比统计成功！");
        log.debug(mapData.toString());
        return new Result(true, MessageConst.ACTION_SUCCESS, mapData);
    }

    @Reference
    private ReportService reportService;

    /**
     * 获取运营统计数据
     *
     * @return
     */
    @RequestMapping("/getBusinessReportData")
    public Result getBusinessReportData() throws Exception {
        Map<String, Object> result = reportService.getBussinessReport();
        System.out.println("result:" + result);
        return new Result(true, MessageConst.ACTION_SUCCESS, result);
    }


    /**
     * 导出运营数据到本地
     * 步骤
     * 1. 创建模板
     * 2. 获取运营统计数据
     * 3. 把运营数据写入到excel
     * 4. 下载excel到本地
     *
     * @return
     */
    @RequestMapping("/exportBusinessReport")
    public Result exportBusinessReport(HttpServletResponse response) {
        try {
            //2. 获取运营统计数据
            Map<String, Object> businessReportData = reportService.getBussinessReport();
            //获取统计日期
            Object reportDate = businessReportData.get("reportDate");
            Object totalMember = businessReportData.get("totalMember");
            Object todayNewMember = businessReportData.get("todayNewMember");
            Object thisWeekNewMember = businessReportData.get("thisWeekNewMember");
            Object thisMonthNewMember = businessReportData.get("thisMonthNewMember");
            Object todayOrderNumber = businessReportData.get("todayOrderNumber");
            Object todayVisitsNumber = businessReportData.get("todayVisitsNumber");
            Object thisWeekOrderNumber = businessReportData.get("thisWeekOrderNumber");
            Object thisWeekVisitsNumber = businessReportData.get("thisWeekVisitsNumber");
            Object thisMonthOrderNumber = businessReportData.get("thisMonthOrderNumber");
            Object thisMonthVisitsNumber = businessReportData.get("thisMonthVisitsNumber");
            List<Map<String, Object>> hotSetmeal = (List<Map<String, Object>>) businessReportData.get("hotSetmeal");

            //3. 把运营数据写入到excel
            //获取excel的输入流对象
            InputStream inputStream = this.getClass().getResourceAsStream("/template/report_template.xlsx");
            //创建工作薄对象
            XSSFWorkbook workbook = new XSSFWorkbook(inputStream);
            //获取工作表对象（sheet）
            XSSFSheet sheet = workbook.getSheet("Sheet1");
            //设置统计日期
            //获取行对象
            Row row = sheet.getRow(2);
            //获取单元格
            Cell cell = row.getCell(5);
            //设置单元格的数据
            cell.setCellValue(String.valueOf(reportDate));

            //设置今日新增会员数
            //获取行对象
            row = sheet.getRow(4);
            //获取单元格
            cell = row.getCell(5);
            //设置单元格的数据
            cell.setCellValue(String.valueOf(todayNewMember));


            //设置总会员数
            //获取行对象
            row = sheet.getRow(4);
            //获取单元格
            cell = row.getCell(7);
            //设置单元格的数据
            cell.setCellValue(String.valueOf(totalMember));


            //设置本周新增会员数
            //获取行对象
            row = sheet.getRow(5);
            //获取单元格
            cell = row.getCell(5);
            //设置单元格的数据
            cell.setCellValue(String.valueOf(thisWeekNewMember));

            //设置本月新增会员数
            //获取行对象
            row = sheet.getRow(5);
            //获取单元格
            cell = row.getCell(7);
            //设置单元格的数据
            cell.setCellValue(String.valueOf(thisMonthNewMember));


            //设置今日预约数
            //获取行对象
            row = sheet.getRow(7);
            //获取单元格
            cell = row.getCell(5);
            //设置单元格的数据
            cell.setCellValue(String.valueOf(todayOrderNumber));

            //设置今日到诊数
            //获取行对象
            row = sheet.getRow(7);
            //获取单元格
            cell = row.getCell(7);
            //设置单元格的数据
            cell.setCellValue(String.valueOf(todayVisitsNumber));


            //设置本周预约数
            //获取行对象
            row = sheet.getRow(8);
            //获取单元格
            cell = row.getCell(5);
            //设置单元格的数据
            cell.setCellValue(String.valueOf(thisWeekOrderNumber));

            //设置本周到诊数
            //获取行对象
            row = sheet.getRow(8);
            //获取单元格
            cell = row.getCell(7);
            //设置单元格的数据
            cell.setCellValue(String.valueOf(thisWeekVisitsNumber));


            //设置本月预约数
            //获取行对象
            row = sheet.getRow(9);
            //获取单元格
            cell = row.getCell(5);
            //设置单元格的数据
            cell.setCellValue(String.valueOf(thisMonthOrderNumber));

            //设置本月到诊数
            //获取行对象
            row = sheet.getRow(9);
            //获取单元格
            cell = row.getCell(7);
            //设置单元格的数据
            cell.setCellValue(String.valueOf(thisMonthVisitsNumber));

            //声明行号
            int rownum = 12;
            for (Map<String, Object> map : hotSetmeal) {
                //获取行对象
                row = sheet.getRow(rownum);
                //
                cell = row.getCell(4);
                cell.setCellValue(String.valueOf(map.get("name")));
                //获取行，给行赋值
                cell = row.getCell(5);
                cell.setCellValue(String.valueOf(map.get("setmeal_count")));
                //获取行，给行赋值
                cell = row.getCell(6);
                cell.setCellValue(String.valueOf(map.get("proportion")));

                rownum++;
            }

            //4. 下载excel到本地
            // 通过输出流进行文件下载
            ServletOutputStream out = response.getOutputStream();
            //指定附件的格式为excel
            response.setContentType("application/vnd.ms-excel");
            //attachment 以附件下载
            //下载弹出框架中的默认的文件名
            response.setHeader("content-Disposition", "attachment;filename=" + reportDate + "_report.xlsx");
            //输出流下载
            workbook.write(out);
            out.flush();
            out.close();
            workbook.close();


        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    @RequestMapping("/getMemberAge")
    public Result getMemberAge() {
        //获取所有身份证信息
        List<String> idNum = memberService.getMemberIDNum();
        //获取所有用户数量
        Integer num = memberService.getMemberNum();

        int[] a = new int[5];//统计不同年龄段人群数量
        //从身份证中截取用户生日
        for (String id : idNum) {

            String birthday = null;//生日
            //身份证位数转换  15转18
            if (id != null && id.length() == 15) {
                //转换为18位身份证
                String id18 = TransferIdUtils.get18Ic(id);
                //截取生日
                birthday = TransferIdUtils.getBirthday(id18);
            } else if (id != null && id.length() == 18) {
                //18位的直接截取生日
                birthday = TransferIdUtils.getBirthday(id);
            } else {
                //位数不对
                throw new RuntimeException("身份证位数不正确");
            }

            //日期格式转换
            Date date = null;//生日
            try {
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
                date = sdf.parse(birthday);
            } catch (ParseException e) {
                e.printStackTrace();
            }

            //求出生日对应年龄
            int age = getAgeByBirth(date);

            //年龄分段
            if (age >= 0 && age < 18) {
                a[0]++; //0-18
            } else if (age >= 18 && age < 30) {
                a[1]++;//18-30
            } else if (age >= 30 && age < 45) {
                a[2]++;//30-45
            } else {
                a[3]++;//45以上
            }
        }
        a[4] = num - a[0] - a[1] - a[2] - a[3];//信息不完整

        //name集合
        List<String> nameList = new ArrayList<>();
        nameList.add("0-18岁");
        nameList.add("18-30岁");
        nameList.add("30-45岁");
        nameList.add("45岁以上");
        nameList.add("信息不完整");
        log.debug("namelist ==============" + nameList);

        //name value映射map的集合
        List<Map<String, Object>> valueMapList = new LinkedList<>();
        for (int i = 0; i < nameList.size(); i++) {
            Map<String, Object> valueMap = new HashMap<>();
            valueMap.put("value", a[i]);
            valueMap.put("name", nameList.get(i));
            valueMapList.add(valueMap);
        }
        //封装数据
        Map<String, Object> map = new HashMap<>();
        map.put("nameList", nameList);
        map.put("valueMapList", valueMapList);
        log.debug("map ========" + map);
        return new Result(true, MessageConst.ACTION_SUCCESS, map);
    }

    @RequestMapping("/getMemberGender")
    public Result getMemberGender() {
        //获取会员性别数据
        Map<String, Integer> sexMap = memberService.getMemberSex();
        //性别列表
        List<String> memberName = new ArrayList<>();
        memberName.add("男");
        memberName.add("女");
        memberName.add("信息未完善");
        log.debug("memberName" + memberName);
        //会员性别信息 列表
        List<Map<String, Object>> memberMapList = new LinkedList<>();


        for (int i = 0; i < memberName.size(); i++) {
            //中间map用于封装信息
            Map<String, Object> valueMap = new HashMap<>();
            String name = memberName.get(i);
            valueMap.put("name", name);
            valueMap.put("value", sexMap.get(name));
            //map封装进入maplist
            memberMapList.add(valueMap);
        }

        //结果封装
        Map<String, Object> result = new HashMap<>();
        result.put("memberName", memberName);
        result.put("memberMapList", memberMapList);
        log.debug("result ===============" + result);
        return new Result(true, MessageConst.ACTION_SUCCESS, result);
    }
}
